﻿//=====================================================================================================
// LocalizationLibrary
// The Localization Library is a collection of reusable software components that provide 
// support for localization. This library enables you to localize WPF, Silverlight and WP7 applications.
// (http://localizationlibrary.codeplex.com)
//=====================================================================================================
// Author: Nicola Gallo (Website: www.nicola.gallo.name, Email: nicolagmt@hotmail.it) 
//=====================================================================================================

namespace SLS.ExClassLib.Loc
{
    //.NET References
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    //LocalizationLibrary References
    using SLS.ExClassLib.Loc.Attributes;
    using  SLS.ExClassLib.Loc.Messaging;
    using SLS.ExClassLib.Loc.Interface;
    /// <summary>
    /// Represents a dynamic resources.
    /// </summary>
    internal class DynamicResource : IResource
    {
        //Fields

        /// <summary>
        /// Gets the dynamic resource items.
        /// </summary>
        protected readonly Dictionary<Language, Object> DynamicResourceItems;

        //Constructors

        /// <summary>
        /// Creates a new instance of the <see cref="DynamicResource"/> class.
        /// </summary>
        /// <param name="resourceID">Specifies the identifier of the resource.</param>
        /// <exception cref="ArgumentException">
        /// Thrown whether <paramref name="resourceID"/> parameter is either null or equals to white space.
        /// </exception>
        public DynamicResource(String resourceID)
        {
            if (String.IsNullOrEmpty(resourceID))
            {
                throw new ArgumentException("resourceID parameter shoul dn't be either null or equals at white space.");
            }
            this.ResourceID = resourceID;
            this.DynamicResourceItems = new Dictionary<Language, Object>();
        }

        //Indexers

        /// <summary>
        /// Gets the text for the input language.
        /// </summary>
        /// <param name="language">Language.</param>
        /// <returns>The value for the input language.</returns>
        public Object this[Language language]
        {
            get
            {
                Object retVal = null;
                if ((language != null) && (this.DynamicResourceItems.ContainsKey(language)))
                {
                    retVal = this.DynamicResourceItems[language];
                }
                return retVal;
            }
        }

        //Properties

        /// <summary>
        /// Gets resource's identifier.
        /// </summary>
        public String ResourceID { get; private set; }

        //Methods

        /// <summary>
        /// Serves as a hash function for <see cref="DynamicResource"/> type.
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return this.ResourceID.GetHashCode();
        }

        /// <summary>
        /// Determines whether the specified <see cref="DynamicResource"/> is equals to the current <see cref="DynamicResource"/>.
        /// </summary>
        /// <param name="obj">Instance.</param>
        /// <returns>True whether the input instance is equals to the current instance otherwise false.</returns>
        public override bool Equals(object obj)
        {
            if (this == obj)
            {
                return true;
            }
            else if ((obj == null) || (obj.GetType() != this.GetType()))
            {
                return false;
            }
            DynamicResource instance = obj as DynamicResource;
            return instance.ResourceID.Equals(this.ResourceID);
        }

        /// <summary>
        /// Add a new localization.
        /// </summary>
        /// <param name="language">Value's language.</param>
        /// <param name="value">Value</param>
        public void Add(Language language, Object value, bool publishNotify) 
        {
            this.Add(language, value, VersionConflictPolicy.KeepExisting, publishNotify);
        }

        /// <summary>
        /// Add a new localization.
        /// </summary>
        /// <param name="language">Value's language.</param>
        /// <param name="value">Value.</param>
        /// <param name="policy">Represents the policy should accomplish the engine in case of version conflicting.</param>
        public void Add(Language language, Object value, VersionConflictPolicy policy, bool publishNotify)
        {
            lock (this.DynamicResourceItems)
	        {
                bool updated = false;
                if (!this.DynamicResourceItems.ContainsKey(language))
                {
                    this.DynamicResourceItems.Add(language, value);
                    updated = true;
                }
                else if (policy == VersionConflictPolicy.OverrideExisting) 
                {
                    this.DynamicResourceItems[language] = value;
                    updated = true;
                }
                if ((updated) && (publishNotify))
                {
                    MessagingManager.Publish(new ResourceMessage(this, Operation.Updated));
                }
	        }
        }

        /// <summary>
        /// Gets the localized languages.
        /// </summary>
        /// <returns>Localized languages.</returns>
        public Language[] GetLocalizedLanguages() 
        {
            List<Language> localizedLangauges = new List<Language>();
            foreach (var item in this.DynamicResourceItems)
            {
                localizedLangauges.Add(item.Key);
            }
            return localizedLangauges.ToArray();
        }

        /// <summary>
        /// Gets localized text.
        /// </summary>
        /// <returns></returns>
        public Object GetLocalizedValue()
        {
            Object retVal = null;
            if (this.DynamicResourceItems.ContainsKey(LocalizationManager.CurrentLanguage))
            {
                retVal = this.DynamicResourceItems[LocalizationManager.CurrentLanguage];
            }
            return retVal;
        }

        /// <summary>
        /// Gets token for the input language.
        /// </summary>
        /// <returns>Token for the input language.</returns>
        public DynamicResourceToken GetToken(Language language)
        {
            DynamicResourceToken retVal = null;
            if (language != null)
            {
                retVal = new DynamicResourceToken(this.ResourceID, language);
                if (this.DynamicResourceItems.ContainsKey(language))
                {
                    retVal.Value =  this.DynamicResourceItems[language];
                }
            }
            return retVal;
        }
    }
}